function varargout = TLMaindialogDlg(action,varargin)

% TL_MAINDIALOG_DLG manages user interface for TargetLink Main Dialog
%
% SYNTAX dlgInfo = TLMaindialogDlg('GetDlgInfo');
%   gets dialog info of TargetLink Main Dialog
%
%   INPUT ARGUMENTS
%   -/-
%
%   OUTPUT ARGUMENTS
%   dlgInfo     dialog information contains pageNames etc.
%
% SYNTAX [sheetDims, ctrlPos] = TLMaindialogDlg('CtrlPositions', pageName, commonGeom, dlgInfo, sheetDims);
%   calculates the control positions of all controls of dialog page: <pageName>
%
%   INPUT ARGUMENTS
%   pageName        name of current page
%   commonGeom      common geometry data
%   dlgInfo         dialog information contains pageNames etc.
%   sheetDims       dimension of sheet
%
%   OUTPUT ARGUMENTS
%   sheetDims       modified dimension of sheet
%   ctrlPos         positions of controls
%
% SYNTAX dlgdata = TLMaindialogDlg('Create', pageName, dlgfig, dlgdata);
%   creates all controls of dialog page: <pageName>
%
%   INPUT ARGUMENTS
%   pageName        name of current page
%   dlgfig          figure handle
%   dlgdata         dialog data
%
%   OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%
% SYNTAX [dlgdata,bModified] = TLMaindialogDlg('Manage', pageName, dlgfig, dlgdata, pageAction);
%   manages all actions of dialog page: <pageName>
%
%   INPUT ARGUMENTS
%   pageName        name of current page
%   dlgfig          figure handle
%   dlgdata         dialog data
%   pageAction      modified control of current page
%
%   OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%   bModified       flag = 1, if dialog data are modified, =0 otherwise
%
% SYNTAX dlgdata = TLMaindialogDlg('Update', dlgfig, dlgdata, pageNum);
%   updates all controls of dialog page: <pageNum>
%
%   INPUT ARGUMENTS
%   dlgfig          figure handle
%   dlgdata         dialog data
%   pageNum         number of current page
%
%   OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%
% SYNTAX TLMaindialogDlg('Apply', dlgfig, dlgdata);
%   writes current blockdata to block and DD
%
%   INPUT ARGUMENTS
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%
%   OUTPUT ARGUMENTS
%   - / -


% Author(s): D. Andoleit, T. Pietzsch
% $RCSfile: TLMaindialogDlg.m $
% $ProjectName: e:/ARC/Components/HostSW/SimulinkBlocksets/TLBlocksets/CommonBlockset/CommonBlockset_UtilityBlocksUI/Sources/MSrc/project.pj $
% $Revision: 1.111 $
% $Date: 2011/09/28 08:51:34MESZ $
%
% Copyright ?2011 dSPACE GmbH. All rights reserved.


switch action
    
    case 'GetDlgInfo'
        hModel = get_param(varargin{1}, 'Handle');
        if strcmp(get_param(hModel, 'Type'), 'block')
            hModel = bdroot(hModel);
        end
        dlgInfo = tl_get_dlginfodefaults('tlutil');
        dlgInfo.bShowBlock   = 0;
        dlgInfo.bShowBrowser = 1;
        dlgInfo.bSim         = 1;
        dlgInfo.pageNames = {
            'Code Generation';...
            'Simulation';...
            'RTOS';...
            'Tools';...
            'Options';...
            'Advanced';...
            'Documentation'};
        dlgInfo.title = ['TargetLink Main Dialog: ' get_param(hModel, 'Name')];
        
        varargout{1} = dlgInfo;
        varargout{2} = get_tlcg_data(hModel);
        
    case 'CtrlPositions'
        pageName     = varargin{1};
        commonGeom   = varargin{2};
        sheetDims    = varargin{4};
        switch pageName
            case 'Documentation'
                bTblBlock = 0;
                bCodeComment = 0;
                [sheetDims,ctrlPos] = ...
                    TLManageDocCtrls('ctrlpos',commonGeom,sheetDims,bCodeComment,bTblBlock);
            otherwise
                eval(['[sheetDims,ctrlPos] = Fcn' strtok(pageName) 'CtrlPositions(commonGeom,sheetDims);']);
        end
        varargout{1} = sheetDims;
        varargout{2} = ctrlPos;
        
    case 'Create',
        pageName = varargin{1};
        dlgfig   = varargin{2};
        dlgdata  = varargin{3};
        pageNum  = find(strcmp(pageName,dlgdata.pageNames));
        
        % DD application name
        dlgdata.ddApplication = dsdd_manage_application('GetApplication','Subsystem',dlgdata.model);
        switch pageName
            case 'Documentation'
                dlgdata = ...
                    TLManageDocCtrls('create',pageNum,dlgfig,dlgdata);
            otherwise
                eval(['dlgdata = FcnCreate' strtok(pageName) 'Page(pageNum,dlgfig,dlgdata);']);
        end
        dlgdata.pageData{pageNum}.ctrlPos = [];
        % create listener for model close event
        objModel = handle(dlgdata.model);
        dlgdata.lis = handle.listener(objModel, 'CloseEvent', 'delete_tlblock(get_param(gcs, ''Handle''));');
        % main dialog blocks in libraries are always locked regardless of whether the
        % library is locked or not
        if strcmp(get_param(dlgdata.model, 'BlockDiagramType'), 'library')
            dlgdata.bLocked = true;
            set(dlgdata.SystemButtons.Close, 'Enable', 'off');
            set(dlgdata.SystemButtons.StatusLabel, 'String', 'Dialog was invoked from a library block, thus it shows dummy data');
        end
        % update simulation toolbar simulation buttons
        FcnUpdateStartStopButtons(dlgdata);
        varargout{1} = dlgdata;
        
    case 'Manage',
        pageName   = varargin{1};
        dlgfig     = varargin{2};
        dlgdata    = varargin{3};
        pageAction = varargin{4};
        pageNum    = find(strcmp(pageName,dlgdata.pageNames));
        switch pageName
            case 'Documentation'
                [dlgdata,bModified] = ...
                    TLManageDocCtrls('callback',pageNum,dlgfig,dlgdata,pageAction);
            otherwise
                eval(...
                    ['[dlgdata,bModified] = FcnManage' strtok(pageName) 'Page(pageNum,dlgfig,dlgdata,pageAction);']);
        end
        varargout{1} = dlgdata;
        varargout{2} = bModified;
        
    case 'ManageSystemIcons',
        dlgfig     = varargin{1};
        dlgdata    = varargin{2};
        pageAction = varargin{3};
        [dlgdata, bModified] = FcnManageSystemIcons(dlgfig,dlgdata,pageAction);
        varargout{1} = dlgdata;
        varargout{2} = bModified;
        
    case 'Update'
        dlgfig   = varargin{1};
        if numel(varargin) >= 3
            dlgdata  = varargin{2};
            pageNum  = varargin{3};
            pageName = dlgdata.pageNames{pageNum};
            switch pageName
                case 'Code Generation'
                    dlgdata = FcnUpdateCodePage(dlgfig,dlgdata,pageNum);
                case 'Simulation'
                    dlgdata = FcnUpdateSimulationPage(dlgfig,dlgdata,pageNum);
                case 'RTOS'
                    dlgdata = FcnUpdateRTOSPage(dlgfig,dlgdata,pageNum);
                case 'Tools'
                    dlgdata = FcnUpdateToolsPage(dlgfig,dlgdata,pageNum);
                case 'Options'
                    dlgdata = FcnUpdateOptionsPage(dlgfig,dlgdata,pageNum);
                case 'Advanced'
                    dlgdata = FcnUpdateAdvancedPage(dlgdata,pageNum);
                case 'Documentation'
                    TLManageDocCtrls('update', pageNum, dlgfig, dlgdata);
            end
        else
            what_to_update = varargin{2};
            dlgdata = get(dlgfig, 'UserData');
            switch what_to_update
                case 'simulation_buttons'
                    % update simulation start/stop button
                    FcnUpdateStartStopButtons(dlgdata);
                case 'TL_subs_display'
                    % actualize TargetLink subsystem list
                    if dlgdata.CurrentPageNum == 1
                        dlgdata = FcnUpdateCodePage(dlgfig,dlgdata,1);
                    end
                case 'simulation_display'
                    % actualize simulation object listbox and simulation object properties display
                    dlgdata = FcnUpdateSimulationPage(dlgfig,dlgdata,2);
                otherwise
                    % actualize all
                    dlgdata = FcnUpdateCodePage(dlgfig,dlgdata,1);
                    dlgdata = FcnUpdateSimulationPage(dlgfig,dlgdata,2);
                    dlgdata = FcnUpdateRTOSPage(dlgfig,dlgdata,3);
            end
            set(dlgfig,'UserData',dlgdata);
        end
        varargout = {dlgdata};
        
    case 'Apply'
        dlgdata = varargin{2};
        bClose  = varargin{3};
        dsdd_manage_application('SetApplication', ...
            'Subsystem',        dlgdata.model, ...
            'Application',      dlgdata.ddApplication);
        [dlgdata, bClose] = tl_apply_blockdata(dlgdata, bClose);
        varargout{1} = dlgdata;
        varargout{2} = bClose;
        
    otherwise
        error(['Invalid action: ''' action '''']);
end
end


%-----------------------------------------------------------------------------------------
% FcnManageSystemIcons manage actions of toolbar icons
%
% INPUT ARGUMENTS
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%   action      action at one control of current page
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%   bModified   flag = 1, if dialog data are modified, =0 otherwise
%-----------------------------------------------------------------------------------------
function [dlgdata, bModified] = FcnManageSystemIcons(dlgfig, dlgdata, action) %#ok

bModified = false;
switch action
    case 'EditCode'
        % open codefiles of all selected items that have one
        selectedSystems = {};
        jSelectedNodes = dlgdata.pageData{1}.subSysTree.hTreeView.selectedNodes;
        userData = get(dlgdata.pageData{1}.jTreeView.UIContainer, 'UserData');
        for m = 1:numel(jSelectedNodes)
            jTmpNode = jSelectedNodes(m);
            tmpChildIdx = find([userData.treeMapping{:,1}] == jTmpNode.hashCode);
            selectedSystems{end+1}.name = userData.treeMapping{tmpChildIdx,3}; %#ok<AGROW>
            selectedSystems{end}.refPath = userData.treeMapping{tmpChildIdx,2}; %#ok<AGROW>
            selectedSystems{end}.type = userData.treeMapping{tmpChildIdx,4}; %#ok<AGROW>
            selectedSystems{end}.path = userData.treeMapping{tmpChildIdx,5}; %#ok<AGROW>
        end
        codeFileInfo = FcnGetCodeFileInfo(selectedSystems);
        for k = 1:numel(codeFileInfo)
            if ~isempty(codeFileInfo(k).rootFile)
                codeedit(codeFileInfo(k).rootFile);
            end
        end
    case 'ViewCode'
        if isempty(dlgdata.pageData{1}.children)
            tlsystems = get_tlsubsystems(bdroot(dlgdata.model));
            tl_create_links_to_model('ShowCodeViewFile',tlsystems{1});
        else
            [model, refModels, subsystems] = FcnGetSelectedItems(dlgdata);
            hTmpSubsystem = get_param(subsystems{1}, 'Handle');
            tl_create_links_to_model('ShowCodeViewFile',hTmpSubsystem);
        end
    case 'SimStart'
        simStat = get_param(dlgdata.model, 'SimulationStatus');
        switch simStat
            case 'stopped'
                tl_sim(dlgdata.model, 'gui');
            case 'paused'
                set_param(dlgdata.model, 'SimulationCommand', 'continue');
            case 'running'
                set_param(dlgdata.model, 'SimulationCommand', 'pause');
            otherwise
                return
        end
    case 'SimStop'
        set_param(dlgdata.model, 'SimulationCommand', 'stop');
        
    otherwise
        error('Invalid callback');
        
end % switch(action)
end % FcnManageSystemIcons


%-----------------------------------------------------------------------------------------
% FcnUpdateStartStopButtons updates the status of start and stop toolbar buttons
%
% INPUT ARGUMENTS
%   dlgdata     handle for dialog figure
%
% OUTPUT ARGUMENTS
%   -/-
%-----------------------------------------------------------------------------------------
function FcnUpdateStartStopButtons(dlgdata)

userDataSimStart = get(dlgdata.SystemButtons.SimStart, 'UserData');
userDataSimStop  = get(dlgdata.SystemButtons.SimStop, 'UserData');
if dlgdata.bLocked
    cDataSimStart = userDataSimStart.cDataEnabled;
    cDataSimStop  = userDataSimStop.cDataDisabled;
    bAllowPlay = false;
    bAllowStop = false;
    tooltip = 'Start simulation';
else
    switch get_param(dlgdata.model, 'SimulationStatus')
        case {'running', 'initializing'}
            cDataSimStart = userDataSimStart.cDataDisabled;
            cDataSimStop  = userDataSimStop.cDataEnabled;
            bAllowPlay = true;
            bAllowStop = true;
            tooltip = 'Pause simulation';
        case {'terminating', 'stopped'}
            cDataSimStart = userDataSimStart.cDataEnabled;
            cDataSimStop  = userDataSimStop.cDataDisabled;
            bAllowPlay = true;
            bAllowStop = false;
            tooltip = 'Start simulation';
        case 'paused'
            hModel = get_param(dlgdata.model, 'Handle');
            hBlock = find_system(hModel, 'SearchDepth', 1, 'MaskType', 'TL_MilHandler');
            if isempty(hBlock)
                % MIL handler block is a key prerequisite for a simulation, thus the model must be in compiled mode
                currentTime = 0;
            else
                currentTime = get_param(hModel, 'SimulationTime');
            end
            if currentTime > 0
                % simulation was paused
                cDataSimStart = userDataSimStart.cDataEnabled;
                cDataSimStop  = userDataSimStop.cDataEnabled;
                bAllowPlay = true;
                bAllowStop = true;
                tooltip = 'Continue simulation';
            else
                % model is in compiled mode
                cDataSimStart = tl_get_icon('Play_16x16');
                cDataSimStop  = userDataSimStop.cDataDisabled;
                bAllowPlay = false;
                bAllowStop = false;
                tooltip = 'Start simulation';
            end
        otherwise
            % remaining simulation status are updating
            cDataSimStart = tl_get_icon('Play_16x16');
            cDataSimStop  = userDataSimStop.cDataDisabled;
            bAllowPlay = false;
            bAllowStop = false;
            tooltip = 'Start simulation';
    end
end
set(dlgdata.SystemButtons.SimStart, ...
    'CData',    cDataSimStart, ...
    'Enable',   flag2str(bAllowPlay), ...
    'TooltipString', tooltip);
set(dlgdata.SystemButtons.SimStop, ...
    'CData',    cDataSimStop, ...
    'Enable',   flag2str(bAllowStop));
end % FcnUpdateStartStopButtons


%-----------------------------------------------------------------------------------------
% FcnCreateCodePage creates the code generation page
%
% INPUT ARGUMENTS
%   pageNum     number of current page
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%-----------------------------------------------------------------------------------------
function dlgdata = FcnCreateCodePage(pageNum,dlgfig,dlgdata) %#ok

enums =  tl_manage_blockset('GetEnums');
dlgdata.currentElement = 1;

% let's check data
tl_handle_warning_state('push');
tl_handle_warning_state('set','State','off');
data = tl_check_blockstruct(dlgdata.data,tl_manage_blockset('GetDataDescription', dlgdata.maskType));
tl_handle_warning_state('pop');
dlgdata.data = data;
ctrlPos = dlgdata.pageData{pageNum}.ctrlPos;

% push warning state and suppress warning messages regarding java callback functions
if get_param(0, 'version') >= 7.6
    bRestoreWarnings = true;
    tl_handle_warning_state('push');
    tl_handle_warning_state('set','MsgId', 'MATLAB:hg:JavaSetHGProperty', 'State', 'off');
else
    bRestoreWarnings = false;
end

%-----------------------------------------------------------
% code generation units groupbox
Children.codeGenUnitsGroupBox = uipanel( ...
    'Parent',            dlgfig, ...
    'Title',            {'Code generation units'}, ...
    'Units',            'pixels', ...
    'Position',          ctrlPos.codeGenUnitsGroupBox);

% Include sub-items checkbox
dlgdata.bGenerateAllCode = false;
Children.inclSubItemsCheckbox = uicontrol( ...
    'Parent',             Children.codeGenUnitsGroupBox, ...
    'String',             'Include sub-items for code generation', ...
    'Style',              'checkbox', ...
    'Enable',             flag2str(dlgdata.bIsFullVs), ...
    'Value',              dlgdata.bGenerateAllCode, ...
    'Position',           ctrlPos.inclSubItemsCheckbox);

%-----------------------------------------------------------
% code options groupbox
Children.codegenOptionsGroupbox = uipanel( ...
    'Parent',            dlgfig, ...
    'Title',            {'Code and logging options'}, ...
    'Units',            'pixels', ...
    'Position',          ctrlPos.codegenOptionsGroupbox);

% log options controls
l = enums(strcmp({enums.name},'GlobalLoggingModeEnum'));
popupString = l.strings;
Children.loggingLabel = uicontrol( ...
    'Parent',            Children.codegenOptionsGroupbox, ...
    'Style',             'text', ...
    'String',            'Global logging option:', ...
    'Position',          ctrlPos.loggingLabel);
Children.loggingPopup = uicontrol( ...
    'Parent',            Children.codegenOptionsGroupbox, ...
    'String',            popupString, ...
    'Style',             'popupmenu', ...
    'Position',          ctrlPos.loggingPopup);

% logging options for referenced models
l = enums(strcmp({enums.name},'RefModelLoggingModeEnum'));
popupString = l.strings;
Children.refLoggingLabel = uicontrol( ...
    'Parent',            Children.codegenOptionsGroupbox, ...
    'Style',             'text', ...
    'String',            'Logging in referenced models:', ...
    'Position',          ctrlPos.refLoggingLabel);
Children.refLoggingPopup = uicontrol( ...
    'Parent',            Children.codegenOptionsGroupbox, ...
    'String',            popupString, ...
    'Style',             'popupmenu', ...
    'BackGroundColor',   'w', ...
    'Position',          ctrlPos.refLoggingPopup);

% code generation mode label
Children.codeGenModeLabel = uicontrol( ...
    'Parent',            Children.codegenOptionsGroupbox, ...
    'Style',             'text', ...
    'String',            'Code generation mode:', ...
    'Position',          ctrlPos.codeGenModeLabel);

% code generation mode popup
l = enums(strcmp({enums.name},'CodeGenerationModeEnum'));
popupString = l.strings;
Children.codeGenModePopup = uicontrol( ...
    'Parent',            Children.codegenOptionsGroupbox, ...
    'String',            popupString, ...
    'Style',             'popupmenu', ...
    'BackGroundColor',   'w', ...
    'Position',          ctrlPos.codeGenModePopup);

% simulation frame configuration controls
Children.prodCodeTargetLabel = uicontrol( ...
    'Parent',            Children.codegenOptionsGroupbox, ...
    'Style',             'text', ...
    'String',            'Code generation target settings:', ...
    'Position',          ctrlPos.prodCodeTargetLabel);

% target popup
Children.targetPopup = uicontrol( ...
    'Parent',            Children.codegenOptionsGroupbox, ...
    'String',            ' ', ...
    'Style',             'popupmenu', ...
    'BackGroundColor',   'w', ...
    'Position',          ctrlPos.targetPopup);

% context menu for targetPopup
showTargetContextMenu = uicontextmenu('Parent', dlgfig);
set(Children.targetPopup, 'UIContextMenu', showTargetContextMenu);
menuTarget.select = uimenu(showTargetContextMenu, ...
    'Label', 'Show ...', ...
    'Callback', sprintf('tldlg(''%s'',gcbf,''showTargetConfigContextMenu'')', dlgdata.pageNames{pageNum}));
set(showTargetContextMenu, 'UserData', menuTarget);

% assembler checkbox
Children.assemblerCheckbox = uicontrol( ...
    'Parent',            Children.codegenOptionsGroupbox, ...
    'Style',             'checkbox', ...
    'String',            'Assembler and C extensions', ...
    'Position',          ctrlPos.assemblerCheckbox);

% pragma checkbox
Children.sectionsCheckbox = uicontrol( ...
    'Parent',            Children.codegenOptionsGroupbox, ...
    'Style',             'checkbox', ...
    'Position',          ctrlPos.sectionsCheckbox);
Children.sectionsLabel = uicontrol( ...
    'Parent',            Children.codegenOptionsGroupbox, ...
    'Style',             'text', ...
    'Min',               0, ...
    'Max',               2, ...
    'String',            ['Enable sections/pragmas/',char(10), ...
    'inline/ISR/user attributes'], ...
    'Position',          ctrlPos.sectionsLabel);

% clean code checkbox
Children.cleanCodeCheckbox = uicontrol( ...
    'Parent',            Children.codegenOptionsGroupbox, ...
    'Style',             'checkbox', ...
    'String',            'Clean code', ...
    'Position',          ctrlPos.cleanCodeCheckbox);

%-----------------------------------------------------------
% generate code groupbox
cData = tl_get_icon('ArrowHeadDown_16x16');

Children.buttonsGroupbox = uipanel( ...
    'Parent',            dlgfig, ...
    'Title',            {''}, ...
    'Units',            'pixels', ...
    'Position',          ctrlPos.buttonsGroupbox);

% generate code button
Children.generateButton = uicontrol( ...
    'Parent',            Children.buttonsGroupbox, ...
    'Style',             'pushbutton', ...
    'String',            'Generate Code', ...
    'Position',          ctrlPos.generateButton);

% build SIL button
Children.buildSILButton = uicontrol( ...
    'Parent',            Children.buttonsGroupbox, ...
    'Style',             'pushbutton', ...
    'String',            'Build SIL', ...
    'Position',          ctrlPos.buildSILButton);
Children.silStepButton = uicontrol( ...
    'Parent',           Children.buttonsGroupbox, ...
    'Style',            'pushbutton', ...
    'CData',            cData, ...
    'Position',         ctrlPos.silStepButton);

silStepMenu = uicontextmenu('Parent', dlgfig);
codegenCB = 'tldlg(''Code Generation'', gcbf, ''generateButton'')';
compSILCB = 'tldlg(''Code Generation'', gcbf, ''compileSILButton'')';
actSILCB  = 'tldlg(''Code Generation'', gcbf, ''activateSILButton'')';
uimenu(silStepMenu, 'Label', 'Generate Code', 'Callback', codegenCB);
uimenu(silStepMenu, 'Label', 'Compile SIL',   'Callback', compSILCB);
uimenu(silStepMenu, 'Label', 'Activate SIL',  'Callback', actSILCB);
set(Children.silStepButton, 'UIContextmenu', silStepMenu);

% build PIL button
Children.buildPILButton = uicontrol( ...
    'Parent',            Children.buttonsGroupbox, ...
    'Style',             'pushbutton', ...
    'String',            'Build PIL', ...
    'Position',          ctrlPos.buildPILButton);
Children.pilStepButton = uicontrol( ...
    'Parent',           Children.buttonsGroupbox, ...
    'Style',            'pushbutton', ...
    'CData',            cData, ...
    'Position',         ctrlPos.pilStepButton);

pilStepMenu = uicontextmenu('Parent', dlgfig);
codegenCB = 'tldlg(''Code Generation'', gcbf, ''generateButton'')';
compPILCB = 'tldlg(''Code Generation'', gcbf, ''compilePILButton'')';
downldCB  = 'tldlg(''Code Generation'', gcbf, ''downloadButton'')';
actPILCB  = 'tldlg(''Code Generation'', gcbf, ''activatePILButton'')';
uimenu(pilStepMenu, 'Label', 'Generate Code', 'Callback', codegenCB);
uimenu(pilStepMenu, 'Label', 'Compile PIL',   'Callback', compPILCB);
uimenu(pilStepMenu, 'Label', 'Download',      'Callback', downldCB);
uimenu(pilStepMenu, 'Label', 'Activate PIL',  'Callback', actPILCB);
set(Children.pilStepButton, 'UIContextmenu', pilStepMenu);

% activate MIL button
Children.activateMILButton = uicontrol( ...
    'Parent',            Children.buttonsGroupbox, ...
    'Style',             'pushbutton', ...
    'String',            'Activate MIL', ...
    'Position',          ctrlPos.activateMILButton);

% activate SIL button
Children.activateSILButton = uicontrol( ...
    'Parent',            Children.buttonsGroupbox, ...
    'Style',             'pushbutton', ...
    'String',            'Activate SIL', ...
    'Position',          ctrlPos.activateSILButton);

% activate PIL button
Children.activatePILButton = uicontrol( ...
    'Parent',            Children.buttonsGroupbox, ...
    'Style',             'pushbutton', ...
    'String',            'Activate PIL', ...
    'Position',          ctrlPos.activatePILButton);

[dlgdata, jTree] = FcnCreateSystemTree(dlgfig, dlgdata, ctrlPos.tlSubsystemListbox);
Children.jTree = jTree;

% In the first update of the tree view, the model node has be expanded.
% Hence we need following flag:
dlgdata.pageData{pageNum}.treeViewIsUpdateFirstTime = false;
dlgdata.pageData{pageNum}.children = Children;

if bRestoreWarnings
    tl_handle_warning_state('pop');
end
end


%-----------------------------------------------------------------------------------------
% FcnManageCodePage manage control actions of Code Options page
%
% INPUT ARGUMENTS
%   pageNum     number of current page
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%   action      action at one control of current page
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%   bModified   flag = 1, if dialog data are modified, =0 otherwise
%-----------------------------------------------------------------------------------------
function [dlgdata, bModified] = FcnManageCodePage(pageNum,dlgfig,dlgdata,action) %#ok

bModified = 0;
Children = dlgdata.pageData{pageNum}.children;

% push warning state and suppress warning messages regarding java callback functions
if get_param(0, 'version') >= 7.6
    bRestoreWarnings = true;
    tl_handle_warning_state('push');
    tl_handle_warning_state('set','MsgId', 'MATLAB:hg:JavaSetHGProperty', 'State', 'off');
else
    bRestoreWarnings = false;
end

switch action
    case 'generateButton'
        tldlg('SystemButtons',dlgfig,'Apply');
        % refresh dialog data after the simulated apply action
        dlgdata = get(dlgfig,'UserData');
        set(dlgfig,'Pointer','watch');
        FcnGenerateCode(dlgdata);
        bModified = 1;
        
    case 'buildSILButton'
        tldlg('SystemButtons',dlgfig,'Apply');
        % refresh dialog data after the simulated apply action
        dlgdata = get(dlgfig,'UserData');
        set(dlgfig,'Pointer','watch');
        FcnBuildSIL(dlgdata);
        bModified = 1;
        
    case 'silStepButton'
        pos = get(Children.silStepButton, 'Position') + get(Children.buttonsGroupbox, 'Position');
        cmenu = get(Children.silStepButton, 'UIContextmenu');
        set(cmenu, 'Position', pos(1:2), 'Visible', 'on');
        bModified = 1;
        
    case 'compileSILButton'
        tldlg('SystemButtons',dlgfig,'Apply');
        % refresh dialog data after the simulated apply action
        dlgdata = get(dlgfig,'UserData');
        set(dlgfig,'Pointer','watch');
        FcnCompileSIL(dlgdata);
        bModified = 1;
        
    case 'buildPILButton'
        tldlg('SystemButtons',dlgfig,'Apply');
        % refresh dialog data after the simulated apply action
        dlgdata = get(dlgfig,'UserData');
        set(dlgfig,'Pointer','watch');
        FcnBuildPIL(dlgdata);
        bModified = 1;
        
    case 'pilStepButton'
        pos = get(Children.pilStepButton, 'Position') + get(Children.buttonsGroupbox, 'Position');
        cmenu = get(Children.pilStepButton', 'UIContextmenu');
        set(cmenu, 'Position', pos(1:2), 'Visible', 'on');
        bModified = 1;
        
    case 'compilePILButton'
        tldlg('SystemButtons',dlgfig,'Apply');
        % refresh dialog data after the simulated apply action
        dlgdata = get(dlgfig,'UserData');
        set(dlgfig,'Pointer','watch');
        FcnCompilePIL(dlgdata);
        bModified = 1;
        
    case 'downloadButton'
        tldlg('SystemButtons',dlgfig,'Apply');
        % refresh dialog data after the simulated apply action
        set(dlgfig,'Pointer','watch');
        dlgdata = get(dlgfig,'UserData');
        FcnDownload(dlgdata);
        bModified = 1;
        
    case 'activateMILButton'
        [model, refModels, subsystemPathes] = FcnGetSelectedItems(dlgdata);
        subsystems = get_param(subsystemPathes, 'Name');
        set(dlgfig,'Pointer','watch');
        FcnChangeSimMode('MIL', subsystems, dlgdata);
        
    case 'activateSILButton'
        [model, refModels, subsystemPathes] = FcnGetSelectedItems(dlgdata);
        subsystems = get_param(subsystemPathes, 'Name');
        set(dlgfig,'Pointer','watch');
        FcnChangeSimMode('SIL', subsystems, dlgdata);
        
    case 'activatePILButton'
        [model, refModels, subsystemPathes] = FcnGetSelectedItems(dlgdata);
        subsystems = get_param(subsystemPathes, 'Name');
        set(dlgfig,'Pointer','watch');
        FcnChangeSimMode('PIL', subsystems, dlgdata);
        
    case 'targetPopup'
        targets = get(Children.targetPopup,'String');
        if ischar(targets)
            dlgdata.data.codeopt.target = targets;
        else
            target = get(Children.targetPopup,'Value');
            dlgdata.data.codeopt.target = targets{target};
        end
        advPageNum = find(strcmp('Advanced', dlgdata.pageNames));
        dlgdata = FcnUpdateAdvancedPage(dlgdata,advPageNum);
        bModified  = 1;
        
    case 'codeGenModePopup'
        dlgdata.data.codegenerationmode = get(Children.codeGenModePopup, 'Value');
        bModified = true;
        
    case 'assemblerCheckbox'
        dlgdata.data.codeopt.assembler = get(Children.assemblerCheckbox,'Value');
        bModified = 1;
        
    case 'sectionsCheckbox'
        dlgdata.data.codeopt.sections = get(Children.sectionsCheckbox,'Value');
        bModified = 1;
        
    case 'cleanCodeCheckbox'
        dlgdata.data.codeopt.cleancode = get(Children.cleanCodeCheckbox,'Value');
        bModified = 1;
        
    case {'decdecimalsPopup' 'hexdecimalsPopup'}
        ds_handle_radiobuttons([Children.decdecimalsPopup Children.hexdecimalsPopup],gcbo);
        dlgdata.data.codeopt.decimals = get(Children.decdecimalsPopup,'Value');
        bModified = 1;
        
    case 'loggingPopup'
        dlgdata.data.logopt.globalloggingmode = get(Children.loggingPopup,'Value');
        bModified = 1;
        
    case 'refLoggingPopup'
        dlgdata.data.logopt.mdlrefmode = get(Children.refLoggingPopup,'Value');
        bModified = 1;
        
    case 'showTargetConfigContextMenu'
        idx = get(Children.targetPopup,'Value');
        codeopt = dlgdata.options.codeopt(idx);
        if isempty(codeopt.cc), codeopt.cc = 'Generic'; end;
        tl_showdlg(codeopt,Children.targetPopup, codeopt.name);
        
    case 'treeViewContext'
        [dlgdata, bModified] = FcnManageContextMenu(dlgfig, dlgdata);
        
    case 'treeViewClick'
        bModified = 1;
        
    case 'inclSubItemsCheckbox'
        dlgdata.bGenerateAllCode = get(Children.inclSubItemsCheckbox,'Value');
        bModified = 1;
        
    otherwise
        error('Invalid callback');
end
set(dlgfig,'Pointer','arrow');

if bRestoreWarnings
    tl_handle_warning_state('pop');
end
end

%-----------------------------------------------------------------------------------------
% FcnCodeCtrlPositions calculates positions for all code option controls
%
% INPUT ARGUMENTS
%   commonGeom      common geometry information
%   sheetDims       dimension of sheet
%
% OUTPUT ARGUMENTS
%   sheetDims       modified dimension of sheet
%   ctrlPos         positions of controls
%
% HINT:
% Positions are calculated from the bottom left of the figure to avoid
% dependencies on figure size
%-----------------------------------------------------------------------------------------
function [sheetDims,ctrlPos] = FcnCodeCtrlPositions(commonGeom,sheetDims) %#ok

strings_and_styles = {...
    'Include sub-items for code generation',    'checkbox'; ...
    'Logging in referenced models:',            'text'; ...
    'Log according to block data',              'popupmenu'; ...
    'Code generation mode:',                    'text'; ...
    {'Standard', 'AUTOSAR', 'RTOS'}             'popupmenu'; ...
    'Code generation target settings:',         'text'; ...
    'HCS12DP512EVB/Metrowerks31',               'popupmenu';...
    'Assembler and C extensions',               'checkbox';...
    '',                                         'checkbox';...
    'Enable sections/pragmas/ ',                'text'; ...
    'Clean code',                               'checkbox';...
    ' Generate Code ',                          'pushbutton'; ...
    ' Activate SIL ',                           'pushbutton'; ...
    ' Compile SIL ',                            'pushbutton'; ...
    ' Build SIL ',                              'pushbutton'; ...
    ' Download ',                               'pushbutton'};

[ ...
    inclSubItemsCheckboxSize, ...
    loggingLabelSize, ...
    loggingPopupSize, ...
    codeGenModeLabelSize, ...
    codeGenModePopupSize, ...
    codeGenTargetLabelSize, ...
    codeGenTargetPopupSize, ...
    assemblerCheckboxSize, ...
    sectionsCheckboxSize, ...
    sectionsLabelSize, ...
    cleanCodeCheckboxSize, ...
    generateCodeButtonSize, ...
    activateXILButtonSize, ...
    compileXILButtonSize, ...
    buildXILButtonSize, ...
    downloadButtonSize] = ...
    ds_get_uicontrol_sizes(commonGeom,strings_and_styles);


% calculate one size for all code generation buttons
controlButtonSize = max([ ...
    generateCodeButtonSize; ...
    activateXILButtonSize; ...
    compileXILButtonSize; ...
    buildXILButtonSize; ...
    downloadButtonSize]);

popupSize = max([ ...
    loggingPopupSize; ...
    codeGenModePopupSize; ...
    codeGenTargetPopupSize]); ...
    
widths = [...
    inclSubItemsCheckboxSize(1) * 1.5, ...
    popupSize(1)];

[col, colWidth, colDelta, rowDelta] = ds_get_gui_columns(widths, commonGeom);

%----------------------------------------------------------
% buttons groupbox (part1)
%----------------------------------------------------------

% to calculate the width of this groupbox the widths of groupboxes
% CodeGenOptions and CodeGenUnits are needed. But to calculate the
% y-position of that groupboxes, the hight of the buttons groupbox is
% needed. Thus calculate only the hight of buttonsGroupbox here and do the
% remaining calculations later

smallButtonHeight = controlButtonSize(2);
bigButtonHeight = controlButtonSize(2) * 1.5;
buttonsGroupboxHeigth = ...
    2 * commonGeom.frameBottomEdgeBuffer ...
    + smallButtonHeight ...
    + bigButtonHeight ...
    + rowDelta;
cx = commonGeom.figSideEdgeBuffer + commonGeom.sheetSideEdgeBuffer;
cy = commonGeom.bottomSheetOffset ...
    + commonGeom.sheetBottomEdgeBuffer;
ctrlPos.buttonsGroupbox = ...
    [cx, cy, 0, buttonsGroupboxHeigth];

%-----------------------------------------------------------
% code options groupbox
%-----------------------------------------------------------

% The number of rowDeltas is 5 because there are no spaces between popup menus
% and their labels above.
% The term 2 * sectionsLabelSize(2) is the height of the ceckbox which is
% expanded over two text lines

codegenGroupboxWidth = colWidth(2) ...
    + 2 * commonGeom.frameSideEdgeBuffer;
codegenGroupboxHeight = ...
    commonGeom.frameBottomEdgeBuffer ...
    + 2 * commonGeom.checkboxHeight + 2 * sectionsLabelSize(2) ... % 3 checkboxes
    + 4 * commonGeom.popupHeight + 4 * commonGeom.textHeight ... % 4 labeled popupmenus
    + 6 * rowDelta ...
    + commonGeom.frameTopEdgeBuffer;
cx = cx + col(2) + colDelta/3;
cy = ctrlPos.buttonsGroupbox(2) + ctrlPos.buttonsGroupbox(4) ...
    + colDelta/3;
ctrlPos.codegenOptionsGroupbox = ...
    [cx,cy,codegenGroupboxWidth codegenGroupboxHeight];

% 1st column
cx = commonGeom.frameSideEdgeBuffer;

% clean code checkbox
cy = commonGeom.frameBottomEdgeBuffer;
ctrlPos.cleanCodeCheckbox = [cx, cy, cleanCodeCheckboxSize];

% section / pragmas / inline / ISR / user attributes
% sections checkbox is splitted in a checkbox without any
% text and a separate lable with text for the sections checkbox
% because the label ranges about two rows

cyLabel = cy + commonGeom.checkboxHeight + rowDelta/2;
ctrlPos.sectionsLabel = ...
    [(cx + sectionsCheckboxSize(1) - 4), cyLabel, sectionsLabelSize.*[1 2]];
cy = cy + sectionsLabelSize(2) * 1.5 + rowDelta;
ctrlPos.sectionsCheckbox = [cx,cy,sectionsCheckboxSize];

% assembler und C extensions checkbox
cy = cy + sectionsLabelSize(2) * 1.5 + rowDelta;
ctrlPos.assemblerCheckbox = [cx,cy,assemblerCheckboxSize];

% target popup
cy = cy + commonGeom.checkboxHeight + rowDelta;
ctrlPos.targetPopup = [cx,cy,popupSize];
cy = cy + commonGeom.popupHeight;
ctrlPos.prodCodeTargetLabel = [cx, cy, codeGenTargetLabelSize];

% code generation mode popup
cy = cy + commonGeom.textHeight + rowDelta;
ctrlPos.codeGenModePopup = [cx, cy, popupSize];
cy = cy + commonGeom.popupHeight;
ctrlPos.codeGenModeLabel = [cx, cy, codeGenModeLabelSize];

% logging in refmodel popup
cy = cy + commonGeom.textHeight + rowDelta;
ctrlPos.refLoggingPopup = [cx,cy,popupSize];
cy = cy + commonGeom.popupHeight;
ctrlPos.refLoggingLabel = [cx,cy,loggingLabelSize];

% logging popup
cy = cy + commonGeom.textHeight + rowDelta;
ctrlPos.loggingPopup = [cx,cy,popupSize];
cy = cy + commonGeom.popupHeight;
ctrlPos.loggingLabel = [cx,cy,loggingLabelSize];

%-----------------------------------------------------------
% code generation units groupbox
%-----------------------------------------------------------

codeGenUnitsGroupBoxWidth = colWidth(1) ...
    + 2 * commonGeom.frameSideEdgeBuffer;

cx = ctrlPos.buttonsGroupbox(1);
cy = ctrlPos.codegenOptionsGroupbox(2);
codeGenUnitsGroupBoxHeight = ctrlPos.codegenOptionsGroupbox(4);
ctrlPos.codeGenUnitsGroupBox =  ...
    [cx, cy, codeGenUnitsGroupBoxWidth, codeGenUnitsGroupBoxHeight];

% 1st row
cy = commonGeom.frameBottomEdgeBuffer;

% include sub-items checkbox
cx = col(1);
ctrlPos.inclSubItemsCheckbox = [cx, cy, inclSubItemsCheckboxSize];

% TargetLink subsystem tree box
% position based on dlgfig
cx = ctrlPos.codeGenUnitsGroupBox(1) + col(1);
cy = ctrlPos.codeGenUnitsGroupBox(2) + ctrlPos.inclSubItemsCheckbox(2) ...
    + ctrlPos.inclSubItemsCheckbox(4) + rowDelta;
treeviewHeight = ...
    codeGenUnitsGroupBoxHeight ...
    - commonGeom.frameBottomEdgeBuffer ...
    - inclSubItemsCheckboxSize(2) ...
    - rowDelta ...
    - commonGeom.frameTopEdgeBuffer;

ctrlPos.tlSubsystemListbox = [cx,cy, colWidth(1), treeviewHeight];

%-----------------------------------------------------------
% buttons groupbox (part2)
%-----------------------------------------------------------
% the dimansions of buttonsGroupbox is precalculated above,
% because the height of the box is needed, before the width
% of the box can be calculated.
ctrlPos.buttonsGroupbox(3) = ...
    ctrlPos.codeGenUnitsGroupBox(3) ...
    + ctrlPos.codegenOptionsGroupbox(3) ...
    + colDelta / 3;
% calculate columns for button groupbox
totalWidth = ctrlPos.buttonsGroupbox(3);
useableWidth = totalWidth - 2 * commonGeom.frameSideEdgeBuffer;
columnWidth = (useableWidth + 2*colDelta/3) / 3;
buttonsCol(1) = col(1);
buttonsCol(2) = buttonsCol(1) + columnWidth;
buttonsCol(3) = buttonsCol(2) + columnWidth;

% enlarge big buttons
smallButtonSize = [columnWidth - 2 * colDelta/3, smallButtonHeight];
bigButtonSize = [columnWidth - 2 * colDelta/3,  bigButtonHeight];

% 1st row;
cy = commonGeom.frameBottomEdgeBuffer;

% activate MIL, activate SIL and activate PIL button
cx = buttonsCol(1);
ctrlPos.activateMILButton = [cx, cy, smallButtonSize];
cx = buttonsCol(2);
ctrlPos.activateSILButton = [cx, cy, smallButtonSize];
cx = buttonsCol(3);
ctrlPos.activatePILButton = [cx, cy, smallButtonSize];

% 2nd row
cy = cy + smallButtonSize(2) + rowDelta;

% generate code button
cx = buttonsCol(1);
ctrlPos.generateButton = [cx, cy, bigButtonSize];

% build SIL button
% this button is splitted into a normal pushbutton and an additional button which
% which makes the context menu visible. The second button is square and has no gap
% to the pushbutton.
iconWidth = 16;
cx = buttonsCol(2);
ctrlPos.buildSILButton = [cx, cy, bigButtonSize(1), bigButtonSize(2)];
cx  = cx + ctrlPos.buildSILButton(3) - iconWidth;
ctrlPos.silStepButton = [cx, cy, iconWidth, bigButtonSize(2)];

% build PIL button
cx = buttonsCol(3);
ctrlPos.buildPILButton = [cx, cy, bigButtonSize(1), bigButtonSize(2)];
cx  = cx + ctrlPos.buildSILButton(3) - iconWidth;
ctrlPos.pilStepButton = [cx, cy, iconWidth, bigButtonSize(2)];

%---------------------------------------
% Calculate extents (sheet dimensions).
width = codeGenUnitsGroupBoxWidth ...
    + codegenGroupboxWidth ...
    + colDelta/3 ...
    + 2 * commonGeom.frameSideEdgeBuffer;

height = ctrlPos.buttonsGroupbox(4) ...
    + colDelta/3 ...
    + ctrlPos.codegenOptionsGroupbox(4) ...
    + commonGeom.sheetBottomEdgeBuffer ...
    + commonGeom.textHeight + rowDelta;

sheetDims = [width,height];
end

%--------------------------------------------------------------------------
% FcnUpdateCodePage updates the controls of the code generation tab
%
% INPUT ARGUMENTS
%   dlgdata     dialog data
%   dlgfig      figure handle of dialog
%   pageNum     page Number (=1 for alarm page)
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%--------------------------------------------------------------------------
function dlgdata = FcnUpdateCodePage(dlgfig,dlgdata,pageNum)

% get essential data
Children = dlgdata.pageData{pageNum}.children;
data = dlgdata.data;

% early return if controls are not available
if isempty(Children)
    return;
end

% push warning state and suppress warning messages regarding java callback functions
if get_param(0, 'version') >= 7.6
    bRestoreWarnings = true;
    tl_handle_warning_state('push');
    tl_handle_warning_state('set','MsgId', 'MATLAB:hg:JavaSetHGProperty', 'State', 'off');
else
    bRestoreWarnings = false;
end

% get context menu children
cmenu = get(Children.silStepButton, 'UIContextMenu');
silCMenuChildren = get(cmenu, 'Children');
cmenu = get(Children.pilStepButton, 'UIContextMenu');
pilCMenuChildren = get(cmenu, 'Children');

% update tree view
jTree = dlgdata.pageData{1}.subSysTree.hTreeView;

% if the user saves the model under another name
% the mapping table has to be manipulated: The old
% name in the contained paths have to replaced by
% new names:
userData = get(jTree.UIContainer, 'UserData');
actualModelName = get_param(bdroot(dlgdata.model), 'Name');
if ~strcmp(actualModelName, userData.model)
    for k = 1:size(userData.treeMapping, 1)
        % change name in refPath
        if ischar(userData.treeMapping{k,2})
            userData.treeMapping{k,2} = regexprep(userData.treeMapping{k,2}, ['^', userData.model], actualModelName);
        end
        % change name in path
        if ischar(userData.treeMapping{k,5})
            userData.treeMapping{k,5} = regexprep(userData.treeMapping{k,5}, ['^', userData.model], actualModelName);
        end
        % change name in name
        if ischar(userData.treeMapping{k,3})
            userData.treeMapping{k,3} = regexprep(userData.treeMapping{k,3}, ['^', userData.model], actualModelName);
        end
    end
    userData.model = actualModelName;
    set(jTree.UIContainer, 'UserData', userData);
    
end
jNodeModel = dlgdata.pageData{1}.treeViewRootNode.jMdlRootNode;
if dlgdata.bIsFullVs
    FcnUpdateTree(jTree, jNodeModel);
end
jNodeDDCodeGenUnits = dlgdata.pageData{1}.treeViewRootNode.jDDRootNode;

% The DD Root node in tree view should only be displayed if
% it has at least one CodeGenreationUnit, that fulfills the conditions
% to be displayed. Following code adds/removes the DD root node:
hDDUnitsRoot = dsdd('GetAttribute', '/Pool/CodeGenerationUnits', 'hDDObject');
bDDNodeHasToBeDisplayed = FcnCodeGenerationNodeHasToBeDisplayed(hDDUnitsRoot);
if bDDNodeHasToBeDisplayed
    if jTree.getRoot.getChildCount == 1
        % DD-Root node isn't displayed, but has to
        % to prevent a crash between java threads, remove the following
        % graphic listener, manipulate the tree and add the listeners back
        jTreeModel = jTree.getTree.getModel;
        jTreeModelListener = jTreeModel.getTreeModelListeners;
        for n = numel(jTreeModelListener):-1:1
            jTreeModel.removeTreeModelListener(jTreeModelListener(n));
        end
        jTreeModel.insertNodeInto(jNodeDDCodeGenUnits, jTree.getRoot, jTree.getRoot.getChildCount);
        % expand DD root node
        jNodePath = javax.swing.tree.TreePath(jNodeDDCodeGenUnits.getPath);
        jTree.tree.expandPath(jNodePath);
        % give listeners back to jTreeModel
        for n = numel(jTreeModelListener):-1:1
            jTreeModel.addTreeModelListener(jTreeModelListener(n));
        end
        % DD root node was inserted -> update the grapic
        FcnUpdateTreeGraphics(jTree);
    end
end
if jTree.getRoot.getChildCount == 2
    FcnUpdateTree(jTree, jNodeDDCodeGenUnits);
end

% In the first update of the tree view, the model node has be expanded.
if ~dlgdata.pageData{pageNum}.treeViewIsUpdateFirstTime
    % it was the first update -> expand the model node!
    dlgdata.pageData{pageNum}.treeViewIsUpdateFirstTime = true;
    jTree.getTree.expandRow(0);
    rowNum = jTree.getTree.getRowCount;
    cnt = 1;
    while rowNum == 1 && cnt < 10
        % update of treeview is necessary for row selection
        rowNum = jTree.getTree.getRowCount;
        pause(0.01);
        cnt = cnt + 1;
    end
    jTree.getTree.setSelectionRow(1);
end

% get all selected items from tree node
[model, refModels, subsystems, incrSubsystems, ...
    codeGenUnits, codeGenUnitGroups, insideRefModels, ...
    refModelsInsideRefModels] = FcnGetSelectedItems(dlgdata);
allSubsystems = get_tlsubsystems(get(dlgdata.model, 'Path'), 0);
numSubsystems = numel(allSubsystems);

%-----------------------------------------------------------
% update all other controls
%-----------------------------------------------------------

bModeEnable      = dlgdata.bIsFullVs && numSubsystems > 0;
bSimconfigEnable = dlgdata.bIsFullVs;
bGenEnable       = true;

% colors for normal/stand alone mode
defaultColor = get(dlgfig,'Color');
if dlgdata.bIsFullVs
    bgColor = 'w';
else
    bgColor = defaultColor;
end

% set colors
if numSubsystems == 0
    listboxColor = defaultColor;
else
    listboxColor = bgColor;
end

% check current code generation configuration
codeopt = dlgdata.options.codeopt;
targets  = {codeopt.name};
tgtIdx   = find(strcmp(targets,data.codeopt.target));
tgtFColor = 'k';
if isempty(tgtIdx)
    set(dlgfig,'Visible','on');
    ds_error_msg({ ...
        'The code generation configuration', ...
        ['   ' data.codeopt.target], ...
        'is not defined in the global TargetLink configuration file', ...
        ['   ' which('tl_global_options')], ...
        'Please select an available configuration' ...
        'if you wish to generate production code.'}, ...
        'MessageNumber',2004,'Title','Invalid Code Generation Configuration');
    tgtFColor = 'r';
    targets = [{data.codeopt.target} targets];
    tgtIdx  = 1;
    bGenEnable = false;
end
bGeneric = strcmp(codeopt(tgtIdx).target,'Generic');

% no simulation configuration specified
if ~isfield(dlgdata.options,'simconfig') || ...
        isempty(dlgdata.options.simconfig) || ...
        bGenEnable == false
    bSimconfigEnable = false;
else
    simconfigIdx = strcmp({dlgdata.options.simconfig.name}, data.frameopt.simconfig);
    if ~any(simconfigIdx)
        bSimconfigEnable = false;
    end
end

% flag to disable some controls if main dialog block resides in library
bModelIsLib = dlgdata.bLocked;

%----------------------------------------------------------
% enable/disable buttons for code generation /
% application building steps
%----------------------------------------------------------

% generate button
bSelectedModel = numel(model) > 0;
bIncludeSubItems = get(dlgdata.pageData{1}.children.inclSubItemsCheckbox, 'Value');
if bSelectedModel && bIncludeSubItems
    subsystems = allSubsystems;
end

bSelectedSubsystems     = numel(subsystems) > 0;
bTLSystemsSelected      = bSelectedSubsystems ||(bSelectedModel && bIncludeSubItems);
bSelectedIncrSubsystems = numel([incrSubsystems, insideRefModels]) > 0;
bSelectedCodeGenUnits   = numel(codeGenUnits) > 0;
bSelectedRefModel       = numel([refModels, refModelsInsideRefModels]) > 0;
bSelectedNormalCodeGenItems = ...
    bSelectedSubsystems ...
    || bSelectedIncrSubsystems ...
    || bSelectedCodeGenUnits ...
    || bSelectedRefModel;
bSelectedCGUGroups = numel(codeGenUnitGroups) > 0;

% button has to be enabled, if normal codegen items are selected or a group and the include button
bGenerateButtonEnabled = ~bModelIsLib ...
    && dlgdata.bIsFullVs ...
    && bGenEnable  ...
    && (bSelectedNormalCodeGenItems || ((bSelectedModel || bSelectedCGUGroups) && bIncludeSubItems));

% build SIL button has only be enabled, if TL subsystem(s) is selected
% or the model and the include checkbox is enabled; codegen units may selected;
% ref models and incr. models must not be selected.
bBuildSILButtonEnabled = ...
    ~bModelIsLib && bGenEnable && dlgdata.bIsFullVs ...
    && bTLSystemsSelected ...
    && ~(bSelectedIncrSubsystems || bSelectedRefModel);

% build PIL button
bBuildPILButtonEnabled = bBuildSILButtonEnabled ...
    && bSimconfigEnable;

% intermediate steps require exisiting source files or s-functions
[bSelectedItemsHaveCodeFiles, ...
    bSubsystemsHaveSfcnDlls, ...
    bHaveHTMLFile] = FcnCheckCodeFilesExist(subsystems, dlgdata);

% activate MIL button: activate if only tl-subsystems are selected
bActivateMILButton = ...
    ~bModelIsLib ...
    && dlgdata.bIsFullVs ...
    && bTLSystemsSelected ...
    && ~bSelectedRefModel ...
    && ~bSelectedIncrSubsystems ...
    && ~bSelectedCodeGenUnits ...
    && ~bSelectedCGUGroups;

% check, if simulation frames of all selected subsystems exist
bAllSubsystemsHaveFrames = true;
for k = 1:numel(subsystems)
    hTmpSystem = get_param(subsystems{k}, 'Handle');
    [tmp,tmp,bTmpHasFrame] = tl_handle_tlsubsystem('check',struct('system',hTmpSystem)); %#ok
    if ~bTmpHasFrame
        bAllSubsystemsHaveFrames = false;
        break;
    end
end

% compile SIL button
bCompileSILButtonEnabled = ...
    bBuildSILButtonEnabled ...
    && bAllSubsystemsHaveFrames;

% compile PIL button
bCompilePILButtonEnabled = ...
    bBuildPILButtonEnabled ...
    && bAllSubsystemsHaveFrames;

% download button
[bTargetIsBuild, bApplIsLoaded] = FcnTargetWasBuilt(dlgdata);
bDownloadButtonEnabled = ...
    bCompilePILButtonEnabled ...
    && bSubsystemsHaveSfcnDlls ...
    && bTargetIsBuild;

% activate SIL button: check if host code was build
applictionName = dsdd_manage_application('GetApplication');
simConfig = tl_get_host_simconfig;

if isempty(simConfig)
    bHostIsBuild = false;
else
    folderHost = [pwd, '